#pragma once
#include <queue>
#include <mutex>
#include <thread>
#include <string>
#include <sstream>
#include <condition_variable>

using namespace std;

namespace CommonSupport
{
    typedef void (*TaskCallBack)(void *const);
    typedef void (*TaskDeleter)(void *const);

    template <class T>
    void deleter(void *const obj)
    {
        typedef typename remove_pointer<T>::type Type;
        delete (Type *)obj;
    }

    string inline getCurrentThreadId()
    {
        stringstream threadId;
        threadId << this_thread::get_id();
        return threadId.str();
    }

    struct Task
    {
        friend class ThreadPool;

        const TaskCallBack callBack;
        const TaskDeleter deleter;
        void *const arg;
        const bool needRun;

    protected:
        Task(bool needRun) : Task(needRun, nullptr, nullptr, nullptr) {}
        Task(bool needRun, TaskCallBack callBack, void *arg, TaskDeleter deleter) : needRun(needRun), callBack(callBack), arg(arg), deleter(deleter) {}

    public:
        ~Task()
        {
            if (deleter != nullptr && arg != nullptr)
                deleter(arg);
        }
    };

    class TaskQueue
    {
    public:
        TaskQueue();
        ~TaskQueue();
        void addTask(Task *task);
        Task *takeTask();
        int size();
        int empty();
        void clear();

    private:
        queue<Task *> taskQueue;
        mutex queueMutex;
        condition_variable_any queueCondition;
    };

    class ThreadPool
    {
    public:
        ThreadPool(int min, int max);
        ~ThreadPool();
        void addTask(TaskCallBack taskCallBack);
        void addTask(TaskCallBack taskCallBack, void *arg);
        void addTask(TaskCallBack taskCallBack, void *arg, TaskDeleter deleter);

    private:
        void managerProcess();
        void createWorkerProcess();
        void workerProcess();

    private:
        // 线程池容纳范围：最小线程数
        const int minNum;
        // 线程池容纳范围：最大线程数
        const int maxNum;
        // 线程池状态：是否需要销毁线程池 - true 是 - fasle 否
        bool shutdown;

        // 工作中的线程数：繁忙的线程数
        int busyNum;
        // 存活的线程数：包括繁忙的和闲置的
        int liveNum;

        // 线程池锁：整个线程池操作需要保护的资源时使用的锁
        mutex poolMutex;
        condition_variable_any poolCondition;

        // 管理者线程
        thread managerThread;

        // 任务队列
        TaskQueue taskQueue;
    };
};

namespace common = CommonSupport;